#pragma once
//#include "ASN1Encodable.h"
#include "TBSVersion.h"
#include "ASN1Integer.h"
#include "Name.h"
#include "ASN1UTCTime.h"
#include "ASN1Sequence.h"
#include "ASN1ObjectIdentifier.h"
#include "ASN1Encoded.h"
#include "Extensions.h"

namespace AppliedCryptography
{
	namespace AC = AppliedCryptography;
	
	/*
	TBSCertificate  ::=  SEQUENCE  {
		version         [0]  EXPLICIT Version DEFAULT v1,
		serialNumber         CertificateSerialNumber,
		signature            AlgorithmIdentifier,
		issuer               Name,
		validity             Validity,
		subject              Name,
		subjectPublicKeyInfo SubjectPublicKeyInfo,
		issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
							 -- If present, version MUST be v2 or v3
		subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
							 -- If present, version MUST be v2 or v3
		extensions      [3]  EXPLICIT Extensions OPTIONAL
							 -- If present, version MUST be v3
	}
	*/
	class TBSCertificateGenerator : public ASN1Sequence
	{
	private:
		TBSVersion*				_version;
		ASN1Integer*			_serialNumber;
		ASN1ObjectIdentifier*	_signatureAlgorithm;
		Name*					_issuer;
		ASN1UTCTime*			_startDate;
		ASN1UTCTime*			_endDate;
		Name*					_subject;
		//ASN1BitString*			_publicKey;
		ASN1Encoded*		_publicKey;
		Extensions*			_extensions;

	public:
		//TBSCertificateGenerator();
		TBSCertificateGenerator(
			TBSVersion* version = new TBSVersion(),
			ASN1Integer* serialNumber = new ASN1Integer(),
			ASN1ObjectIdentifier* signAlgoOID = new ASN1ObjectIdentifier(),
			Name* issuer = new Name(),
			ASN1UTCTime* startDate = new ASN1UTCTime(),
			ASN1UTCTime* endDate = new ASN1UTCTime(),
			Name* subject = new Name(),
			ASN1Encoded* publicKey = new ASN1Encoded(),
			Extensions* extensions = new Extensions());

		virtual ~TBSCertificateGenerator();

	private:
		virtual ASN1Sequence& add(ASN1Encodable& obj);
		virtual ASN1Encodable& get(unsigned int index) const;

	public:
		virtual unsigned int size() const;
		virtual std::vector<byte> getContentBits() const;

	public:
		virtual TBSCertificateGenerator& setSerialNumber(unsigned long serialNumber);
		virtual TBSCertificateGenerator& setIssuer(Name& issuer);
		virtual TBSCertificateGenerator& setSubject(Name& subject);
		virtual TBSCertificateGenerator& setStartDate(ASN1UTCTime& startDate);
		virtual TBSCertificateGenerator& setEndDate(ASN1UTCTime& endDate);
		virtual TBSCertificateGenerator& setSignatureAlgorithm(ASN1ObjectIdentifier& algorithm);
		virtual TBSCertificateGenerator& setPublicKey(ASN1Encoded& key);
		virtual TBSCertificateGenerator& setExtensions(Extensions& extensions);
	};
}; // namespace AppliedCryptography
